import datetime
from typing import Dict, List, Tuple

from src.baseapp.model.BaseOrmOpeator import OrmOperator
from src.baseapp.model.userServiceModel.userModel import UserModel
from src.baseapp.controller.baseController import BaseController
from src.utils.userToken import token_tool

# 已登录的用户缓存在这里
login_users = []  # List[int]


class UserController(BaseController):

    def __init__(self):
        super().__init__()
        self.orm = OrmOperator(UserModel)

    def login(self, username: str, password: str) -> Tuple[int, Dict]:
        response = self.response_data()
        try:
            user: UserModel = self.orm.equal(UserModel.username, username).equal(UserModel.is_delete, 0).get_one()
            if user and user.password == password:
                response.data['token'] = token_tool.token_encode(user)
                login_users.append(user.user_id)
            else:
                response.code = 401
                response.msg = 'error username or password'
        except Exception as e:
            response.code = 500
            response.msg = str(e)
        return response.code, response.to_dict

    def logout(self, token: str) -> Tuple[int, Dict]:
        response = self.response_data()
        try:
            user_info = token_tool.token_decode(token)
            login_users.remove(user_info['user_id'])
        except Exception as e:
            response.code = 401
            response.msg = str(e)
        return response.code, response.to_dict

    def get_user_info(self, token: str) -> Tuple[int, Dict]:
        response = self.response_data()
        try:
            user_info = token_tool.token_decode(token)
            user: UserModel = self.orm.equal(UserModel.user_id, user_info['user_id']).equal(UserModel.is_delete, 0).get_one()
            response.data['user_info'] = {
                'user_id': user.user_id,
                'username': user.username,
                'email': user.email,
                'is_admin': user.is_admin
            }
        except Exception as e:
            response.code = 401
            response.msg = str(e)
        return response.code, response.to_dict

    def get_user_list(self) -> Tuple[int, Dict]:
        response = self.response_data()
        try:
            user_list = self.orm.equal(UserModel.is_delete, 0).get_all()
            response.data['user_list'] = [user.to_dict() for user in user_list]
        except Exception as e:
            response.code = 500
            response.msg = str(e)
        return response.code, response.to_dict

    def add_user(self, username: str, password: str, email: str) -> Tuple[int, Dict]:
        response = self.response_data()
        try:
            user = UserModel(username=username, password=password, email=email)
            self.orm.insert_data(user)
        except Exception as e:
            response.code = 500
            response.msg = str(e)
        return response.code, response.to_dict

    def __update_user(self, token: str, update_data: Dict[str, str]) -> Tuple[int, Dict]:
        response = self.response_data()
        try:
            user_info = token_tool.token_decode(token)
            user: UserModel = self.orm.equal(UserModel.user_id, user_info['user_id']).equal(UserModel.is_delete, 0).get_one()
            for key, value in update_data.items():
                if key not in ('password', 'email'):
                    raise ValueError(f'{key} is not allowed to update')
                setattr(user, key, value)
            self.orm.update_data(user)
        except Exception as e:
            response.code = 500
            response.msg = str(e)
        return response.code, response.to_dict

    def update_user(self, token: str, update_data: Dict[str, str]) -> Tuple[int, Dict]:
        return self.__update_user(token, update_data)

    def reset_password(self, token: str, old_password: str, new_password: str) -> Tuple[int, Dict]:
        response = self.response_data()
        try:
            user_info = token_tool.token_decode(token)
            user: UserModel = self.orm.equal(UserModel.user_id, user_info['user_id']).equal(UserModel.is_delete, 0).get_one()
            if user.password == old_password:
                self.__update_user(token, {'password': new_password})
            else:
                response.code = 401
                response.msg = 'old password is incorrect'
        except Exception as e:
            response.code = 500
            response.msg = str(e)
        return response.code, response.to_dict

    def delete_user(self, token: str, user_id: int) -> Tuple[int, Dict]:
        response = self.response_data()
        try:
            user_info = token_tool.token_decode(token)
            user: UserModel = self.orm.equal(UserModel.user_id, user_info['user_id']).equal(UserModel.is_delete, 0).get_one()
            if user.is_admin == 1:
                delete_user: UserModel = self.orm.equal(UserModel.user_id, user_id).equal(UserModel.is_delete, 0).get_one()
                delete_user.is_delete = 1
                self.orm.update_data(delete_user)
            else:
                response.code = 401
                response.msg = 'no permission'
        except Exception as e:
            response.code = 500
            response.msg = str(e)
        return response.code, response.to_dict
